\chapter{QMultiHash}

template <typename Key, typename T> class QMultiHash

QMultiHash 类是一个便利的 QHash 派生类，提供多值哈希表功能。更多内容...

\begin{tabular}{|r|l|}
	\hline
	属性 & 方法 \\
	\hline
    头文件  &	\hl{\#include <QMultiHash>} \\
    \hline
    qmake: & QT += core    \\
    \hline
    基类: & QHash    \\
	\hline
\end{tabular}

\begin{compactitem}
\item 所有成员列表，包括继承的成员
\end{compactitem}

\begin{notice}
该类中的所有函数都是可重入的。
\end{notice}


\section{公共成员函数}


\begin{longtable}[l]{|r|m{28em}|}   
    \hline
    返回类型 	& 函数 \\
    \hline
    &QMultiHash(const QHash<Key, T> \emph{\&other}) \\
    \hline
	&QMultiHash(InputIterator \emph{begin}, InputIterator \emph{end}) \\
    \hline
	&QMultiHash(std::initializer\_list<std::pair<Key, T>> \emph{list}) \\
    \hline
	&QMultiHash()\\
\hline
typename QHash<Key, T>::const\_iterator &	constFind(const Key \emph{\&key}, const T \emph{\&value}) const \\
\hline
bool 	& contains(const Key \emph{\&key}, const T \emph{\&value}) const \\
\hline
int &	count(const Key \emph{\&key}, const T \emph{\&value}) const \\
\hline
typename QHash<Key, T>::iterator & find(const Key \emph{\&key}, const T \emph{\&value}) \\
\hline
typename QHash<Key, T>::const\_iterator &	find(const Key \emph{\&key}, const T \emph{\&value}) const \\
\hline
typename QHash<Key, T>::iterator &	insert(const Key \emph{\&key}, const T \emph{\&value}) \\
\hline
int &	remove(const Key  \emph{\&key}, const T  \emph{\&value}) \\
\hline
typename QHash<Key, T>::iterator &	replace(const Key \emph{\&key}, const T \emph{\&value}) \\
\hline
void 	& swap(QMultiHash<K, V>  \emph{\&other})\\
\hline
QList 	& uniqueKeys() const\\
\hline
QMultiHash<K, V> \& &	unite(const QMultiHash<K, V> \emph{\&other}) \\
\hline
QList<T> &	values(const Key \&key) const \\
\hline
QMultiHash<K, V> 	&operator+(const QMultiHash<K, V> \emph{\&other}) const\\
\hline
QMultiHash<K, V> \& &	operator+=(const QMultiHash<K, V> \emph{\&other})\\
    \hline
\end{longtable}

\section{相关非成员函数}

\begin{longtable}[l]{|r|l|}   
    \hline
    返回类型 	& 函数 \\
    \hline
    uint &	qHash(const QMultiHash<Key, T> \emph{\&key}, uint \emph{seed} = 0) \\ 
    \hline
\end{longtable}

\section{详细描述}

QMultiHash<Key, T> 是一种 Qt 泛型容器类。它继承 QHash 并扩展了一些便利的功能，使之比 QHash 更适合存储多值哈希。多值哈希是一种允许将多个值关联到同一个键的哈希。

因为 QMultiHash 继承 QHash，所有 QHash 的功能也适用于 QMultiHash。例如，可以使用 isEmpty() 测试哈希表是否为空，可以使用 QHash 的迭代器类（例如 QHashIterator）遍历 QMultiHash。但是与 QHash 不同，QMultiHash 提供的 insert() 函数允许同一个键插入多个元素。而 replace() 函数对应于 QHash::insert()。此外，该类还提供便利的 operator+() 和 operator+=() 运算符。

与 QMultiMap 不同，QMultiHash 不对插入的元素排序。唯一的保证是共享同一键的元素将按照从最新到最早插入的顺序连续出现。

例子：

\begin{cppcode}
QMultiHash<QString, int> hash1, hash2, hash3;

hash1.insert("plenty", 100);
hash1.insert("plenty", 2000);
// hash1.size() == 2

hash2.insert("plenty", 5000);
// hash2.size() == 1

hash3 = hash1 + hash2;
// hash3.size() == 3
\end{cppcode}

%%%%%%%

与 QHash 不同，QMultiHash 不提供 operator[] 运算符。如果想用特定键访问最新插入的元素，使用 value() 或 replace()。

如果想取得单个键关联的所有值，
可以使用 values(const Key \&key)，
该函数返回一个 QList：

\begin{cppcode}
QList<int> values = hash.values("plenty");
for (int i = 0; i < values.size(); ++i)
    cout << values.at(i) << Qt::endl;
\end{cppcode}

共享同一键的元素按照从最新到最早插入的顺序返回。

更有效的方法是传递键调用 find() 取得第一个元素的 STL 风格迭代器，从该元素开始遍历：

\begin{cppcode}
QMultiHash<QString, int>::iterator i = hash.find("plenty");
while (i != hash.end() && i.key() == "plenty") {
    cout << i.value() << Qt::endl;
    ++i;
}
\end{cppcode}

QMultiHash 键和值的数据类型必须是可赋值数据类型。
不能存储类似 QWidget 这样的对象作为值；
应该存储 QWidget *。
另外，QMultiHash 的键类型必须提供 operator==() 运算符， 
并且在键类型的命名空间内还必须有一个为键类型参数返回哈希值的 qHash() 函数。具体请参考 QHash 文档。

\begin{seeAlso}
QHash，QHashIterator，QMutableHashIterator 和 QMultiMap。
\end{seeAlso}

\section{成员函数文档}

QMultiHash::QMultiHash(const QHash<Key, T> \emph{\&other})

构造一个 \emph{other} 的副本（可能是一个 QHash 或 QMultiHash）。

\begin{seeAlso}
operator=()。
\end{seeAlso}

template QMultiHash::QMultiHash(InputIterator \emph{begin}, InputIterator \emph{end})

用迭代器范围 [\emph{begin}, \emph{end}) 内每个元素的副本构造一个多值哈希表。
需要满足下列两个条件之一：迭代范围内的元素是包含 first 和 second 数据成员的对象（像 QPair，std::pair等），
分别可以转换为 Key 类型和 T 类型；或者迭代器必须含有 key() 和 value() 成员函数，分别返回可以转换为 Key 类型的键 T 类型的值。

Qt 5.14 中引入该函数。

QMultiHash::QMultiHash(std::initializer\_list<std::pair<Key, T>> \emph{list})

用初始化列表 \emph{list} 中每个元素的副本构造一个哈希表。

只有当程序在 C++11 模式下编译时，该函数才可用。

Qt 5.1 中引入该函数。

QMultiHash::QMultiHash()

构造一个空哈希表。

typename QHash<Key, T>::const\_iterator QMultiHash::constFind(const Key \emph{\&key}, const T \emph{\&value}) const

返回迭代器，指向哈希表中键为 \emph{key}，值为 \emph{value} 的元素。

如果哈希表中不包含这样的元素，该函数返回 constEnd()。

Qt 4.3 中引入该函数。

\begin{seeAlso}
QHash::constFind().
\end{seeAlso}

bool QMultiHash::contains(const Key \emph{\&key}, const T \emph{\&value}) const

如果该哈希表包含键为 \emph{key}，值为 \emph{value} 的元素，返回 true；否则返回 false。

Qt 4.3 中引入该函数。

\begin{seeAlso}
QHash::contains().
\end{seeAlso}

int QMultiHash::count(const Key \emph{\&key}, const T \emph{\&value}) const

返回键为 \emph{key}，值为 \emph{value} 的元素个数。

Qt 4.3 中引入该函数。

\begin{seeAlso}
QHash::count()。
\end{seeAlso}

typename QHash<Key, T>::iterator QMultiHash::find(const Key \emph{\&key}, const T \emph{\&value})

返回迭代器，指向键为 \emph{key}，值为 \emph{value} 的元素。
如果哈希表中不包含这样的元素，该函数返回 end()。

如果哈希表包含多个键为  \emph{key}，值为 \emph{value} 的元素，迭代器指向最新插入的元素。

Qt 4.3 中引入该函数。

\begin{seeAlso}
另请参阅 QHash::find()。
\end{seeAlso}

typename QHash<Key, T>::const\_iterator QMultiHash::find(const Key \emph{\&key}, const T \emph{\&value}) const

这是一个重载函数。

Qt 4.3 中引入该函数。

typename QHash<Key, T>::iterator QMultiHash::insert(const Key \emph{\&key}, const T \emph{\&value})

用键 \emph{key} 和值 \emph{value} 插入一个新元素。

如果哈希表中已经存在相同键的元素，该函数将创建一个新元素。
（这与 replace() 不同，replace() 是覆盖已经存在元素的值。)

\begin{seeAlso}
replace()。
\end{seeAlso}

int QMultiHash::remove(const Key \emph{\&key}, const T \emph{\&value})

从哈希表中移除所有键为 \emph{key}，值为 \emph{value} 的元素。返回被移除元素的个数。

Qt 4.3 中引入该函数。

\begin{seeAlso}
QHash::remove()。
\end{seeAlso}

typename QHash<Key, T>::iterator QMultiHash::replace(const Key \emph{\&key}, const T \emph{\&value})

用键 \emph{key} 和值 \emph{value} 插入一个新元素。

如果已经存在键为 \emph{key} 的元素，该元素的值将被 \emph{value} 替换。

如果有多个键为 \emph{key} 的元素，最新插入的元素的值将被 \emph{value} 替换。

\begin{seeAlso}
另请参阅 insert()。
\end{seeAlso}

void QMultiHash::swap(QMultiHash<K, V> \emph{\&other})

将 \emph{other} 哈希表与本哈希表。该操作非常快，永远不失败。

Qt 4.8 中引入该函数。

QList QMultiHash::uniqueKeys() const

以升序返回哈希表中所有键的列表。在哈希表中多次出现的键在返回的列表中只出现一次。

Qt 5.13 中引入该函数。

\begin{seeAlso}
keys() 和 values()。
\end{seeAlso}

QMultiHash<K, V> \&QMultiHash::unite(const QMultiHash<K, V> \emph{\&other})

将 \emph{other} 哈希表中的所有元素插入到本哈希表中，返回本哈希表的引用。

Qt 5.13 中引入该函数。

\begin{seeAlso}
insert()。
\end{seeAlso}

QList QMultiHash::values(const Key \emph{\&key}) const

这是一个重载函数。

按照从最新到最早插入的顺序，返回所有与键 \emph{key} 相关联的值的列表。

\begin{seeAlso}
count() 和 insert()。
\end{seeAlso}

QMultiHash<K, V> QMultiHash::operator+(const QMultiHash<K, V> \emph{\&other}) const

返回一个哈希表，该哈希表包含本哈希表和 \emph{other} 哈希表中的所有元素。
如果一个键在两个哈希表中同时存在，结果哈希表将多次包含这个键。

\begin{seeAlso}
另请参阅 operator+=()。
\end{seeAlso}

QMultiHash<K, V> \&QMultiHash::operator+=(const QMultiHash<K, V> \emph{\&other})

将 \emph{other} 哈希表中的所有元素插入到本哈希表中，返回本哈希表的引用。

\begin{seeAlso}
unite() 和 insert()。
\end{seeAlso}

\section{相关非成员函数}

template <typename Key, typename T> uint qHash(const QMultiHash<Key, T> \emph{\&key}, uint \emph{seed} = 0)

返回 \emph{key} 的哈希值，使用 \emph{seed} 来随机化计算结果。

类型 \hl{T} 必须被 qHash() 支持。

Qt 5.8 中引入该函数。